package com.itheima.stock.service.impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.itheima.stock.common.StockInfoConfig;
import com.itheima.stock.common.domain.*;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.resp.PageResult;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service("stockService")
@Slf4j
public class StockServiceImpl implements StockService {

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    /**
     * 获取国内最新大盘指数详情
     * @return
     */
    @Override
    public R<List<InnerMarketDomain>> getInnerStockMarket() {
        //获取最近股票有效交易日,精确到分钟
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        //设置成伪数据
        lastAvDate="20211226105600";
        List<InnerMarketDomain> infos = stockMarketIndexInfoMapper.getInnerStockMarket(stockInfoConfig.getInner(),lastAvDate);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }

    /**
     * 查询最新板块数据前10
     * @return
     */
    @Override
    public R<List<StockBlockDomain>> getSectorAllLimit() {
        List<StockBlockDomain> maps = stockBlockRtInfoMapper.getSectorAllLimit();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据");
        }
        return R.ok(maps);
    }

    /**
     * 沪深两市个股涨幅分时行情数据
     * @return
     */
    @Override
    public R<List<StockUpDownDomain>> getUpDownAllLimit() {
        List<StockUpDownDomain> maps = stockRtInfoMapper.getUpDownAllLimit();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据");
        }
        return R.ok(maps);
    }

    /**
     * 沪深两市个股行情列表查询 ,以时间顺序和涨幅排序分页查询
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public R<PageResult<StockUpDownDomain>> getUpDownAllPage(Integer page, Integer pageSize) {
        PageHelper.startPage(page,pageSize);
        List<StockUpDownDomain> list = stockRtInfoMapper.getUpDownAllPage();
        if (CollectionUtils.isEmpty(list)) {
            R.error(ResponseCode.DATA_ERROR.getMessage());
        }
        PageInfo<StockUpDownDomain> pageInfo = new PageInfo<>(list);
        PageResult<StockUpDownDomain> pageResult = new PageResult<>(pageInfo);
        return R.ok(pageResult);
    }

    /**
     * 沪深两市涨跌停分时行情数据查询，查询T日每分钟的涨跌停数据
     * @return
     */
    @Override
    public R<Map> getUpDownCount() {
        //获取到最近的股票有效交易日,精确到分钟
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        lastAvDate = "20211226";
        List<Map> upCount = stockRtInfoMapper.getUpDownCount(lastAvDate,1);
        List<Map> downCount = stockRtInfoMapper.getUpDownCount(lastAvDate,0);
        HashMap<String, List<Map>> map = new HashMap<>();
        map.put("upList",upCount);
        map.put("downList",downCount);
        return R.ok(map);
    }

    /**
     * 涨幅榜数据分页导出到excel
     * @param response
     * @param page
     * @param pageSize
     */
    @Override
    public void exportStockExcel(HttpServletResponse response, Integer page, Integer pageSize){
        try {
            //设置响应数据格式
            response.setContentType("application/vnd.ms-excel");
            //设置编码
            response.setCharacterEncoding("utf-8");
            //防止中文乱码
            String fileName = URLEncoder.encode("stockRt", "UTF-8");
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //获取导出的分页数据
            PageHelper.startPage(page,pageSize);
            List<StockUpDownDomain> maps = this.stockRtInfoMapper.getUpDownAllPage();
            //转化成StockExcleDomain对象
            Gson gson = new Gson();
            List<StockExcelDomain> excelDomains=maps.stream().map(map->{
                StockExcelDomain excelDomain = gson.fromJson(gson.toJsonTree(map), StockExcelDomain.class);
                return excelDomain;
            }).collect(Collectors.toList());
            EasyExcel.write(response.getOutputStream(),StockExcelDomain.class).sheet("股票数据").doWrite(excelDomains);
        } catch (IOException e) {
            log.info("股票数据导出异常,当前页:{},每页大小:{},异常信息{},",page,pageSize,e.getMessage());
        }
    }

    /**
     * 统计两市成交量在每分钟的之和的统计
     * @return
     */
    @Override
    public R<Map> getStockTravolCompare() {
        //获取最新股盘日期
        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
        String lastAvDate = DateTimeUtil.parseToString4Stock(target);
        lastAvDate = "20211229140000";
        //获取前一次的股盘日期
        String yesAvDate = DateTimeUtil.parseToString4Stock(DateTimeUtil.getPreviousTradingDay(target));
        yesAvDate = "20211228140000";
        List<Map> volList = this.stockRtInfoMapper.getStockTravolCompare(lastAvDate,1);
        List<Map> yesvolList = this.stockRtInfoMapper.getStockTravolCompare(yesAvDate,0);
        HashMap<String,List<Map>> map = new HashMap<>();
        map.put("volList",volList);
        map.put("yesVolList",yesvolList);
        return R.ok(map);
    }

    /**
     * 查询当前时间下股票的涨跌幅度区间统计功能
     * @return
     */
    @Override
    public R<Map> getStockUpDownScope() {
        //获取最新股票日期
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        lastAvDate = "2021-12-31 14:58:00";
        List<Map> maps = stockRtInfoMapper.getStockUpDownScope(lastAvDate);
        //获取去股票涨幅区间的集合
        List<String> upDownRange = stockInfoConfig.getUpDownRange();
        //将list集合下的字符串映射成Map对象
        List<Map> orderMap = upDownRange.stream().map(key -> {
            Optional<Map> title = maps.stream().filter(map -> key.equals(map.get("title"))).findFirst();
            //判断对应的map是否存在
            Map tmp = null;
            if (title.isPresent()) {
                tmp = title.get();
            } else {
                tmp = new HashMap();
                tmp.put("title", key);
                tmp.put("count", 0);
            }
            return tmp;
        }).collect(Collectors.toList());
        HashMap<String,Object> infos = new HashMap<>();
        infos.put("time",lastAvDate);
        infos.put("infos",orderMap);
        return R.ok(infos);
    }

    /**
     * 查询单个个股的分时行情数据，查询时间周期是T日开盘到当前时间
     * @return
     */
    @Override
    public R<List<StockScreenMinDomain>> getStockScreenMinuteSharing(String code) {
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        lastAvDate="20220106092500";
        List<StockScreenMinDomain> list = stockRtInfoMapper.getStockScreenMinuteSharing(lastAvDate,code);
        return R.ok(list);
    }

    /**
     * 单个个股日K 数据查询 ，可以根据时间区间查询数日的K线数据
     * @param code
     * @return
     */
    @Override
    public R<List<StockScreenDayDomain>> getDayKLinData(String code) {
        //获取当前日期前推20天
        Date forwardDate = DateTime.now().minusDays(20).toDate();
        List<StockScreenDayDomain> list = stockRtInfoMapper.getDayKLinData(forwardDate,code);
        return R.ok(list);
    }

    @Override
    public R<List<StockBusiness>> findAllBusiness() {
        List<StockBusiness> list = stockBusinessMapper.findAll();
        return R.ok(list);
    }


}
